import string
import types

from header_common import *

from module_strings import *
from module_sounds import *
from module_items import *
from module_troops import *
from module_factions import *
from module_quests import *
from module_party_templates import *
from module_parties import *
from module_scenes import *
from module_scripts import *
from module_mission_templates import *
from module_game_menus import *
from module_particle_systems import *
from module_scene_props import *


def get_id_value(tag, identifier):
  tag_type = -1
  id_no = -1
  if (tag == "str"):
    id_no = find_object(strings,identifier)
    tag_type = tag_string
  elif (tag == "itm"):
    id_no = find_object(items,identifier)
    tag_type = tag_item
  elif (tag == "trp"):
    id_no = find_object(troops,identifier)
    tag_type = tag_troop
  elif (tag == "fac"):
    id_no = find_object(factions,identifier)
    tag_type = tag_faction
  elif (tag == "qst"):
    id_no = find_object(quests,identifier)
    tag_type = tag_quest
  elif (tag == "pt"):
    id_no = find_object(party_templates,identifier)
    tag_type = tag_party_tpl
  elif (tag == "p"):
    id_no = find_object(parties,identifier)
    tag_type = tag_party
  elif (tag == "scn"):
    id_no = find_object(scenes,identifier)
    tag_type = tag_scene
  elif (tag == "mt"):
    id_no = find_object(mission_templates,identifier)
    tag_type = tag_mission_tpl
  elif (tag == "mnu"):
    id_no = find_object(game_menus,identifier)
    tag_type = tag_menu
  elif (tag == "script"):
    id_no = find_object(scripts,identifier)
    tag_type = tag_script
  elif (tag == "psys"):
    id_no = find_object(particle_systems,identifier)
    tag_type = tag_particle_sys
  elif (tag == "spr"):
    id_no = find_object(scene_props,identifier)
    tag_type = tag_scene_prop
  elif (tag == "snd"):
    id_no = find_object(sounds,identifier)
    tag_type = tag_sound
  return (tag_type, id_no)
  
def get_identifier_value(str):
  underscore_pos = string.find(str, "_")
  result = -1
  if (underscore_pos > 0):
    tag_str = str[0:underscore_pos]
    id_str  = str[underscore_pos + 1:len(str)]
    (tag_type, id_no) = get_id_value(tag_str,id_str)
    if (tag_type > 0):
      if (id_no < 0):
        print "Error: Unable to find object:" + str
      else:
        result = id_no | (tag_type << op_num_value_bits)
    else:
      print "Error: Unrecognized tag:" +tag_str + "in object:" + str
  else:
    print "Error: Invalid object:" +str + ".Variables should start with $ sign and references should start with a tag"
  return result

def load_variables(export_dir):
  variables = []
  try:
    file = open(export_dir + "variables.txt","r")
    var_list = file.readlines()
    file.close()
    for v in  var_list:
      vv = string.strip(v)
      if vv:
        variables.append(vv)
  except:
    print "variables.txt not found. Creating new variables.txt file"
  return variables

def save_variables(export_dir,variables_list):
  file = open(export_dir + "variables.txt","w")
  for variable in variables_list:
    file.write("%s\n"%variable)
  file.close()

def add_cookie(cookies_list,cookie_string):
  found = 0
  result = -1
  for i_t in xrange(len(cookies_list)):
    if cookie_string == cookies_list[i_t]:
      found = 1
      result = i_t
      break
  if not found:
    cookies_list.append(cookie_string)
    result = len(cookies_list) - 1
  return result

def get_cookie(cookies_list,cookie_string):
  found = 0
  result = -1
  for i_t in xrange(len(cookies_list)):
    if cookie_string == cookies_list[i_t]:
      found = 1
      result = i_t
      break
  if not found:
    print "ERROR: input token not found:" + cookie_string
    cookies_list.append(cookie_string)
    result = len(cookies_list) - 1
  return result


def check_varible_not_defined(variable_string,variables_list):
  for i_t in xrange(len(variables_list)):
    if variable_string == variables_list[i_t]:
      print "WARNING: Variable name used for both local and global contexts:" + variable_string
      break
    
def add_get_variable(variable_string,variables_list):
  found = 0
  result = -1
  for i_t in xrange(len(variables_list)):
    if variable_string == variables_list[i_t]:
      found = 1
      result = i_t
      break
  if not found:
    variables_list.append(variable_string)
    result = len(variables_list) - 1
  return result


def process_param(param,global_vars_list,local_vars_list):
  result = 0
  if (type(param) == types.StringType):
    if (param[0] == '$'):
      check_varible_not_defined(param[1:], local_vars_list)
      result = add_get_variable(param[1:], global_vars_list)
      result |= opmask_variable
    elif (param[0] == ':'):
      check_varible_not_defined(param[1:], global_vars_list)
      result = add_get_variable(param[1:], local_vars_list)
      result |= opmask_local_variable
    else:
      result = get_identifier_value(param.lower())
      if (result < 0):
        print "ERROR: Illegal Identifier:" + param
  else:
    result = param
  return result

def save_statement(ofile,statement,variable_list,local_vars_list):
  opcode =   0  
  operand1 = 0
  operand2 = 0
  operand3 = 0
  if ((type(statement) != types.ListType) and (type(statement) != types.TupleType)):
    opcode = statement
  else:
    opcode = statement[0]
    if len(statement) > 1:
      operand1 = process_param(statement[1],variable_list,local_vars_list)
    if len(statement) > 2:
      operand2 = process_param(statement[2],variable_list,local_vars_list)
    if len(statement) > 3:
      operand3 = process_param(statement[3],variable_list,local_vars_list)
  ofile.write("%d %d %d %d "%(opcode,operand1,operand2,operand3))

def save_statement_block(ofile,statement_block,variable_list):
  local_vars = []
  ofile.write(" %d "%(len(statement_block)))
  for statement in statement_block:
    save_statement(ofile,statement,variable_list,local_vars)

def save_simple_triggers(ofile,triggers,variable_list):
  ofile.write("%d\n"%len(triggers))
  for trigger in triggers:
    ofile.write("%f "%(trigger[0]))
    save_statement_block(ofile,trigger[1]  , variable_list)
    ofile.write("\n")
  ofile.write("\n")
